package com.tyx.chargingpile.aop;

import com.tyx.chargingpile.Enum.ServiceMessageEume;
import com.tyx.chargingpile.cache.SocketChannelMap;
import com.tyx.chargingpile.pojo.SocketMessage;
import com.tyx.chargingpile.vo.SocketResponseResult;
import com.tyx.chargingpile.service.MessageService;
import com.tyx.chargingpile.service.SocketMessageService;
import com.tyx.chargingpile.util.DateUtils;
import com.tyx.chargingpile.util.Util;
import io.netty.channel.ChannelHandlerContext;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * 业务报文aop
 */
@Aspect
@Component
public class ServiceMessageAop {

    @Autowired
    SocketMessageService socketMessageService;

    private final static Logger LOGGER = LoggerFactory.getLogger(ServiceMessageAop.class);


    @Pointcut("execution(public * com.tyx.chargingpile.service.impl.*.*(..))")
    public void messageLog(){
    }

    @Before("messageLog()")
    public void doBefore(JoinPoint joinPoint) throws Exception {
        Object[] obj = joinPoint.getArgs();
        ChannelHandlerContext channelHandlerContext = (ChannelHandlerContext) obj[0];
        // 这是后台调用前置接口，给电桩下行的数据，不用做记录
            if (obj[1] instanceof Map){
            return;
        }
        byte[] context = (byte[]) obj[1];
        String commandId = MessageService.getCommandControl(context);
        SocketMessage socketMessage = setSocketMessage(context,1);
        if(StringUtils.isEmpty(commandId)){
            socketMessageService.add(socketMessage);
            return;
        }
        String deviceId = null;
        if(commandId.equals(ServiceMessageEume.REGISTER.getCode())){
            deviceId = MessageService.analysisMessage(context,ServiceMessageEume.REGISTER.getUpLinePath()).get("pileNum");
            deviceId = deviceId.substring(1,deviceId.length());
        }
        else{
            deviceId = SocketChannelMap.getDeviceId(channelHandlerContext.channel().id().toString());
        }
        //判断除了注册和心跳报文外，其他收到的报文都更新心跳时间
        if(!commandId.equals(ServiceMessageEume.REGISTER.getCode()) && !commandId.equals(ServiceMessageEume.HEART.getCode())){
            SocketChannelMap.updateLastSurvivalTime(deviceId);
        }
        socketMessage.setCommandId(commandId);
        socketMessage.setDeviceId(deviceId);
        socketMessageService.add(socketMessage);
    }

    @AfterReturning(returning = "ret",pointcut = "messageLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        if(ret == null){
            return;
        }
        // 处理完请求，返回内容
        SocketResponseResult socketResponseResult = (SocketResponseResult) ret;
        ChannelHandlerContext channelHandlerContext = socketResponseResult.getChannelHandlerContext();
        byte[] context = socketResponseResult.getContext();
        String commandId = MessageService.getCommandControl(context);
        SocketMessage socketMessage = setSocketMessage(context,2);
        if(StringUtils.isEmpty(commandId)){
            socketMessageService.add(socketMessage);
            return;
        }
        String deviceId = SocketChannelMap.getDeviceId(channelHandlerContext.channel().id().toString());
        if(StringUtils.isEmpty(deviceId)){
            socketMessage.setCommandId(commandId);
            socketMessageService.add(socketMessage);
            return;
        }
        socketMessage.setCommandId(commandId);
        socketMessage.setDeviceId(deviceId);
        socketMessageService.add(socketMessage);
    }

    private SocketMessage setSocketMessage(byte[] context,Integer upOrDwnLink){
        SocketMessage socketMessage = new SocketMessage();
        socketMessage.setUpOrDownLink(upOrDwnLink);
        socketMessage.setCreateDateTime(DateUtils.now());
        socketMessage.setMessageContent(Util.BCD2String(context));
        return socketMessage;
    }
}
